package com.zshan.clinic.admin.service.patient;

import com.zshan.clinic.admin.constant.Constants;
import com.zshan.clinic.admin.entity.vo.MedicalFieldVo;
import com.zshan.clinic.admin.entity.vo.PatientInfoDetailVo;
import com.zshan.clinic.admin.entity.vo.PatientInfoPageVo;
import com.zshan.clinic.admin.mapper.patient.SpecPatientMapper;
import com.zshan.clinic.admin.service.config.MedicalFieldService;
import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.constant.MedicalConstant;
import com.zshan.clinic.common.enums.EthnicityEnum;
import com.zshan.clinic.common.enums.FieldScopeEnum;
import com.zshan.clinic.common.enums.GenderEnum;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.page.PageInfo;
import com.zshan.clinic.common.util.page.PageUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.common.util.validate.IdCardUtils;
import com.zshan.clinic.common.util.validate.PhoneValidator;
import com.zshan.clinic.database.dao.ClinicPatientMapper;
import com.zshan.clinic.database.model.ClinicPatient;
import com.zshan.clinic.database.model.ClinicPatientExample;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 会员档位
 * @author lichen
 */
@Service
@Slf4j
public class ClinicPatientService {

    @Autowired
    private ClinicPatientMapper patientInfoMapper;

    @Autowired
    private SpecPatientMapper specPatientMapper;

    @Autowired
    private MedicalFieldService medicalFieldService;

    /**
     * 根据身份证号查询患者信息
     * @param clinicId
     * @param idCard
     * @return
     */
    public ClinicPatient getPatientByIdCard(Long clinicId, String idCard) {
        ClinicPatientExample example = new ClinicPatientExample();
        ClinicPatientExample.Criteria criteria = example.createCriteria();
        criteria.andIdCardEqualTo(idCard);
        criteria.andClinicIdEqualTo(clinicId);
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        List<ClinicPatient> clinicPatientList = patientInfoMapper.selectByExample(example);
        return CollectionUtils.isEmpty(clinicPatientList) ? null : clinicPatientList.get(0);

    }

    /**
     * 查询患者列表
     * @param clinicId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public List<PatientInfoPageVo> getPatientList(Long clinicId, String patientName, Integer pageNo, Integer pageSize) {
        return specPatientMapper.getPatientList(clinicId,patientName,PageUtils.getOffset(pageNo,pageSize),pageSize);
    }

    /**
     * 获取患者详情
     * @param clinicId
     * @param patientId
     * @return
     */
    public PatientInfoDetailVo getPatientDetail(Long clinicId,Long patientId){
        PatientInfoDetailVo patientInfoDetailVo = specPatientMapper.getPatientDetail(clinicId,patientId);
        if(patientInfoDetailVo == null){
            return null;
        }
        List<MedicalFieldVo> medicalFieldVoList = medicalFieldService.getMedicalFieldList(FieldScopeEnum.ALL.getValue(),Arrays.asList(MedicalConstant.JWS, MedicalConstant.GMS));
        patientInfoDetailVo.setFieldList(medicalFieldVoList);
        return patientInfoDetailVo;
    }

    /**
     * 分页查询患者信息
     */
    public PageInfo<ClinicPatient> getPatientListByCondition(Long clinicId, String patientName, Integer pageNo, Integer pageSize) {
        ClinicPatientExample example = new ClinicPatientExample();
        ClinicPatientExample.Criteria criteria = example.createCriteria();
        if (StringUtil.isNotBlank(patientName)) {
            criteria.andPatientNameLike("%" + patientName + "%");
        }
        if (clinicId != null) {
            criteria.andClinicIdEqualTo(clinicId);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        Long totalCount = patientInfoMapper.countByExample(example);
        if (totalCount == null || totalCount == 0) {
            return PageInfo.build();
        }
        example.setOffset(PageUtils.getOffset(pageNo, pageSize));
        example.setLimit(pageSize);
        example.setOrderByClause("create_time desc");
        List<ClinicPatient> patientList = patientInfoMapper.selectByExample(example);
        return new PageInfo<>(totalCount, patientList);
    }

    /**
     * 添加患者信息
     */
    @Transactional(rollbackFor = Exception.class)
    public ClinicPatient addPatient(ClinicPatient patientInfo) {
        validatePatient(patientInfo);
        patientInfo.setIsDelete(YesOrNoEnum.NO.getValue());
        patientInfo.setIsEnabled(YesOrNoEnum.YES.getValue());
        patientInfo.setCreateTime(new Date());
        patientInfoMapper.insertSelective(patientInfo);
        return patientInfo;
    }

    /**
     * 校验患者信息
     */
    public void validatePatient(ClinicPatient patient) {
        patient.setPatientName(StringUtil.removeAllWhitespace(patient.getPatientName()));
        if (StringUtil.isBlank(patient.getPatientName())) {
            throw new BusinessFailException("姓名不能为空");
        }
        if (patient.getPatientName().length() > Constants.PATIENT_NAME_LENGTH) {
            throw new BusinessFailException("姓名最多"+Constants.PATIENT_NAME_LENGTH+"个字！");
        }
        if(StringUtil.isBlank(patient.getPatientGender())){
            patient.setPatientGender(GenderEnum.UNKNOWN.getValue());
        }
        if(!GenderEnum.isValue(patient.getPatientGender())){
            throw new BusinessFailException("性别错误！");
        }
        patient.setPatientPhone(StringUtil.removeAllWhitespace(patient.getPatientPhone()));
        if (StringUtil.isBlank(patient.getPatientPhone()) && StringUtil.isBlank(patient.getIdCard())) {
            throw new BusinessFailException("手机号和证件号不能为同时为空");
        }
        if(StringUtil.isNotBlank(patient.getPatientPhone())){
            if(!PhoneValidator.isValidMobile(patient.getPatientPhone())){
                throw new BusinessFailException("手机号格式错误！");
            }
            Long patientCount = getPatientCountByPhone(patient.getClinicId(),patient.getPatientId(),patient.getPatientPhone());
            if(patientCount > CommonConstant.DEFAULT_0){
                throw new BusinessFailException("当前手机号已被占用，请更换手机号再试！");
            }
        }
        if(StringUtil.isNotBlank(patient.getIdCard())){
            if(!IdCardUtils.isValidFormat(patient.getIdCard())){
                throw new BusinessFailException("身份证号格式错误！");
            }
            Long cardEmpCount = getPatientCountByIdCard(patient.getClinicId(),patient.getPatientId(),patient.getIdCard());
            if(cardEmpCount > CommonConstant.DEFAULT_0){
                throw new BusinessFailException("当前身份证号已被占用，请更换身份证再试！");
            }
            if(patient.getSolarBirthday() == null){
                //自动计算阳历生日
                patient.setSolarBirthday(IdCardUtils.extractBirthDate(patient.getIdCard()));
            }
            if(patient.getLunarBirthday() == null){
                //自动计算阴历生日
                patient.setLunarBirthday(IdCardUtils.extractLunarBirthday(patient.getIdCard()));
            }
            if(patient.getAgeYear() == null){
                patient.setAgeYear(IdCardUtils.getAgeYearFromIdCard(patient.getIdCard()));
            }
            if(patient.getAgeMonth() == null){
                patient.setAgeMonth(IdCardUtils.getAgeMonthFromIdCard(patient.getIdCard()));
            }
        }
        patient.setCompany(StringUtil.removeAllWhitespace(patient.getCompany()));
        if(StringUtil.isNotBlank(patient.getCompany())){
            if(patient.getCompany().length() > Constants.PATIENT_COMPANY_LENGTH){
                throw new BusinessFailException("单位最多"+Constants.PATIENT_COMPANY_LENGTH+"个字！");
            }
        }
        patient.setJob(StringUtil.removeAllWhitespace(patient.getJob()));
        if(StringUtil.isNotBlank(patient.getJob())){
            if(patient.getJob().length() > Constants.PATIENT_JOB_LENGTH){
                throw new BusinessFailException("职业最多"+Constants.PATIENT_JOB_LENGTH+"个字！");
            }
        }
        patient.setRemark(StringUtil.removeAllWhitespace(patient.getRemark()));
        if(StringUtil.isNotBlank(patient.getRemark())){
            if(patient.getRemark().length() > Constants.PATIENT_REMARK_LENGTH){
                throw new BusinessFailException("备注最多"+Constants.PATIENT_REMARK_LENGTH+"个字！");
            }
        }
        if(StringUtil.isNotBlank(patient.getEthnicity())){
            if(!EthnicityEnum.isValue(patient.getEthnicity())){
                throw new BusinessFailException("民族错误");
            }
        }
        if(StringUtil.isBlank(patient.getSortNum())){
            patient.setSortNum(CommonConstant.DEFAULT_1);
        }
    }

    /**
     * 根据身份证号查询患者
     * @param clinicId
     * @param patientId
     * @param idCard
     * @return
     */
    public Long getPatientCountByIdCard(Long clinicId, Long patientId, String idCard) {
        ClinicPatientExample example = new ClinicPatientExample();
        ClinicPatientExample.Criteria criteria = example.createCriteria();
        criteria.andIdCardEqualTo(idCard);
        criteria.andClinicIdEqualTo(clinicId);
        if(!StringUtil.isBlank(patientId)){
            criteria.andPatientIdNotEqualTo(patientId);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        return patientInfoMapper.countByExample(example);
    }

    /**
     * 根据手机号查询用户数量
     * @param clinicId
     * @param patientId
     * @param patientPhone
     * @return
     */
    public Long getPatientCountByPhone(Long clinicId,Long patientId, String patientPhone) {
        ClinicPatientExample example = new ClinicPatientExample();
        ClinicPatientExample.Criteria criteria = example.createCriteria();
        criteria.andPatientPhoneEqualTo(patientPhone);
        criteria.andClinicIdEqualTo(clinicId);
        if(!StringUtil.isBlank(patientId)){
            criteria.andPatientIdNotEqualTo(patientId);
        }
        criteria.andIsDeleteEqualTo(YesOrNoEnum.NO.getValue());
        return patientInfoMapper.countByExample(example);
    }

    /**
     * 根据主键查询患者信息
     */
    public ClinicPatient getPatientById(Long patientId) {
        if (StringUtil.isBlank(patientId)) {
            return null;
        }
        ClinicPatient patient = patientInfoMapper.selectByPrimaryKey(patientId);
        if (patient == null || YesOrNoEnum.YES.getValue().equals(patient.getIsDelete())) {
            return null;
        }
        return patient;
    }

    /**
     * 修改患者信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePatient(ClinicPatient patientInfo) {
        validatePatient(patientInfo);
        ClinicPatient dbPatient = getPatientById(patientInfo.getPatientId());
        if (dbPatient == null) {
            throw new BusinessFailException("患者信息不存在");
        }
        updatePatientInfo(patientInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updatePatientInfo(ClinicPatient patientInfo) {
        patientInfo.setUpdateTime(new Date());
        patientInfoMapper.updateByPrimaryKeySelective(patientInfo);
    }

    /**
     * 更新患者最新就诊信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePatientLastVisit(ClinicPatient patientInfo){
        ClinicPatient dbPatient = getPatientById(patientInfo.getPatientId());
        if (dbPatient == null) {
            throw new BusinessFailException("患者信息不存在");
        }
        updatePatientInfo(patientInfo);
    }


    /**
     * 删除患者信息（逻辑删除）
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletePatient(ClinicPatient patientInfo) {
        ClinicPatient dbPatient = getPatientById(patientInfo.getPatientId());
        if (dbPatient == null) {
            throw new BusinessFailException("患者信息不存在");
        }
        dbPatient.setIsDelete(YesOrNoEnum.YES.getValue());
        dbPatient.setUpdateUserId(patientInfo.getUpdateUserId());
        dbPatient.setUpdateBy(patientInfo.getUpdateBy());
        dbPatient.setUpdateTime(new Date());
        patientInfoMapper.updateByPrimaryKeySelective(dbPatient);
    }

    /**
     * 启用患者信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void enablePatient(ClinicPatient patientInfo) {
        ClinicPatient dbPatient = getPatientById(patientInfo.getPatientId());
        if (dbPatient == null) {
            throw new BusinessFailException("患者信息不存在");
        }
        if (YesOrNoEnum.YES.getValue().equals(dbPatient.getIsEnabled())) {
            return;
        }
        dbPatient.setIsEnabled(YesOrNoEnum.YES.getValue());
        dbPatient.setUpdateUserId(patientInfo.getUpdateUserId());
        dbPatient.setUpdateBy(patientInfo.getUpdateBy());
        dbPatient.setUpdateTime(new Date());
        patientInfoMapper.updateByPrimaryKeySelective(dbPatient);
    }

    /**
     * 停用患者信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void disablePatient(ClinicPatient patientInfo) {
        ClinicPatient dbPatient = getPatientById(patientInfo.getPatientId());
        if (dbPatient == null) {
            throw new BusinessFailException("患者信息不存在");
        }
        if (YesOrNoEnum.NO.getValue().equals(dbPatient.getIsEnabled())) {
            return;
        }
        dbPatient.setIsEnabled(YesOrNoEnum.NO.getValue());
        dbPatient.setUpdateUserId(patientInfo.getUpdateUserId());
        dbPatient.setUpdateBy(patientInfo.getUpdateBy());
        dbPatient.setUpdateTime(new Date());
        patientInfoMapper.updateByPrimaryKeySelective(dbPatient);
    }

}
